import jwt from 'jsonwebtoken';
import { useMysql } from '../mysql/index.js';
// Token 验证中间件
export const verifyToken = async (req, res, next) => {
    // 从请求头中获取 Authorization
    const authHeader = req.headers['authorization'];
    if (!authHeader) {
        return res.status(401).send({
            code: 401,
            message: '未提供 Token',
        });
    }

    // 检查 Authorization 格式是否正确（Bearer <token>）
    const tokenParts = authHeader.split(' ');
    if (tokenParts.length !== 2 || tokenParts[0] !== 'Bearer') {
        return res.status(401).send({
            code: 401,
            message: 'Token 格式错误',
        });
    }
    // 提取 Token
    const token = tokenParts[1];

    try {
        // 验证 Token(有效/未过期)
        const decoded = jwt.verify(token, 'root');
        // 检查 Token 是否在白名单中(1条记录无需数据返回)
        const sql = 'SELECT 1 FROM token WHERE token = ? AND user_id = ? LIMIT 1';
        await useMysql(sql, [token, decoded.userId]);
        // 将解码后的用户信息挂载到 req 对象上
        req.user = decoded;
        next(); // 继续执行后续逻辑
    } catch (err) {
        res.status(401).send({
            code: 401,
            message: 'Token 无效或已过期',
        });
    }
};

/**
 * TokenCreate 方法
 * @param {object} payload - 携带数据
 * @param {string} key - 密钥
 * @param {string} validity - 有效期
 *  @returns {object} { token, createdAt, expiresAt } - 生成的token、创建时间和过期时间
 */
export const TokenCreate = (payload, key, validity) => {
    try {
        // 使用jsonwebtoken的sign方法生成token
        const token = jwt.sign(payload, key, { expiresIn: validity });
        // 获取当前时间作为创建时间
        const createdAt = new Date();
        // 计算过期时间
        const expiresInSeconds = jwt.decode(token).exp; // 获取Token的过期时间戳（秒）
        const expiresAt = new Date(expiresInSeconds * 1000); // 转换为Date对象

        // 返回生成的token和过期时间
        return { token, createdAt, expiresAt };
    } catch (error) {
        // 如果生成token过程中出现错误，抛出异常
        throw new Error('Token生成失败: ' + error.message);
    }
}
/**
 * TokenRemove 方法
 * @param {string} token - 要删除的 Token
 * @returns {object} - 返回操作结果
 */
export const TokenRemove = async (token) => {
    try {
        // 直接删除 Token
        const deleteSql = 'DELETE FROM token WHERE token = ?';
        await useMysql(deleteSql, [token]);

        return {
            success: true,
            message: '退出登录成功',
        };
    } catch (error) {
        // 如果操作过程中出现错误，抛出异常
        throw new Error('退出登录失败: ' + error.message);
    }
};